home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / clang / jcool01.zip / RANDOM.H < prev    next >
C/C++ Source or Header  |  1992-08-14  |  7KB  |  156 lines

  1. //
  2. // Copyright (C) 1991 Texas Instruments Incorporated.
  3. //
  4. // Permission is granted to any individual or institution to use, copy, modify,
  5. // and distribute this software, provided that this complete copyright and
  6. // permission notice is maintained, intact, in all copies and supporting
  7. // documentation.
  8. //
  9. // Texas Instruments Incorporated provides this software "as is" without
  10. // express or implied warranty.
  11. //
  12. // Created: MBN 09/29/89 -- Initial design and implementation
  13. // Updated: MBN 01/03/90 -- Correctly generate numbers within specified range
  14. //
  15. // The Random  class is  publicly derived from  Generic and implements  several
  16. // varieties  of  general-purpose  random number  generators   as described  in
  17. // Chapter 7 of "Numerical Recipes in C".  The  ANSI C draft standard specifies
  18. // the rand() function that allows  an application to obtain successive  random
  19. // numbers in  a sequence by repeated  calls.  However,  system-supplied random
  20. // number generators in the form of the  rand() function  are generally of poor
  21. // quality, particularly  with  regards to their  randomness of distribution of
  22. // random numbers. Specifically,  system  random number generators   are almost
  23. // always  linear congruential genarators whose period  is not very  large. The
  24. // ANSI C  draft  specification only requires a  modulus of 32767, which can be
  25. // disasterous for such uses as a Monte Carlo integration over 10^6 points.
  26. //
  27. // The Random class allows an application to select one of five types of random
  28. // number generators based upon the usage requirements. Each generator function
  29. // has different characteristics. The first two use the system rand() function,
  30. // while the last  three  are  self-contained,  portable  implementations.  The
  31. // first, SIMPLE, uses the system-supplied rand()  function where speed  is the
  32. // predominant concern.  Although  sequential correlation of  successive random
  33. // values is still a high probability, this function at  least corrects for the
  34. // weakness of many system  random  generator functions where the value's least
  35. // significant bits are  very often much less random  than the most significant
  36. // bits. The second, SHUFFLE,   uses  the    rand() function  and   a shuffling
  37. // procedure where random numbers are cached in  a buffer and selected randomly
  38. // to break up  sequential correlation  in the system-supplied   function.  The
  39. // third, ONE_CONGRUENTIAL, uses one linear  congruential generator  instead of
  40. // the rand() function to   implement an  efficient,  portable  random   number
  41. // generator that guarantees   there is no  sequential  correlation between the
  42. // random values returned.   The fourth, THREE_CONGRUENTIAL, uses three  linear
  43. // congruential  generators  to implement  a  portable random number  generator
  44. // whose period is  essentially infinite  and has no   sequential correlations.
  45. // Finally, SUBTRACTIVE  is   an implementation of   a  portable  random number
  46. // generator  as suggested  by  Knuth in Volume   two of "The  Art of  Computer
  47. // Programming" that does not use linear congruential generators, but rather an
  48. // original subtractive method.
  49. //
  50. // The Random class contains  several  private data slots used  by  the various
  51. // random number generator functions.  In addition,  each instance contains the
  52. // lower and upper bounds of the range of random numbers desired and  a pointer
  53. // a   specific generator  function.  One  public  constructors  is provided to
  54. // facilitate the  creation  of floating point random number generator objects.
  55. // Methods  are available  to  get and  set the    seed,  select the  generator
  56. // function, and get the next integer or floating point random number.
  57.  
  58.  
  59. #ifndef RANDOMH                    // If no definition for Random
  60. #define RANDOMH                    // define the random symbol
  61.  
  62. const int RND_BUF_SIZE = 128;            // Anti-correlation buffer size
  63.  
  64. class CoolRandom;                // Forward reference class
  65. typedef double (CoolRandom::*RNG)();        // CoolRandom number function type
  66. enum RNG_TYPE {SIMPLE,SHUFFLE,ONE_CONGRUENTIAL,THREE_CONGRUENTIAL,SUBTRACTIVE};
  67.  
  68. #define MOD 714025                // Modulus for shuffle 
  69. #define MULT 1366                // Multiplier for shuffle
  70. #define INCR 150889                // Increment for shuffle
  71.  
  72. #define MOD1 259200                // Modulus 1 for 3 cong gen  
  73. #define MULT1 7141                // Multiplier 1 for 3 cong gen
  74. #define INCR1 54773                // Increment 1 for 3 cong gen 
  75. #define RMOD1 (1.0/MOD1)            // Factor for 3 cong gen   
  76. #define MOD2 134456                // Modulus 2 for 3 cong gen  
  77. #define MULT2 8121                // Multiplier 2 for 3 cong gen
  78. #define INCR2 28411                // Increment 2 for 3 cong gen 
  79. #define RMOD2 (1.0/MOD2)            // Factor 2 for 3 cong gen   
  80. #define MOD3 243000                // Modulus 3 for 3 cong gen  
  81. #define MULT3 4561                // Multiplier 3 for 3 cong gen
  82. #define INCR3 51349                // Increment 3 for 3 cong gen 
  83.  
  84. #define MBIG 1000000000                // Big constant for Knuth
  85. #define MSEED 161803398                // Seed constant for Knuth
  86. #define FAC (1.0/MBIG)                // Factor for Knuth
  87. #define KNUTH_SPECIAL 56            // Table size for Knuth
  88.  
  89. class CoolRandom {
  90. public:
  91.   CoolRandom (RNG_TYPE, int seed=1, float lower=0.0, float upper=100.0);
  92.   ~CoolRandom ();                    // Destructor
  93.  
  94.   inline int get_seed () const;            // Get current seed value
  95.   inline void set_seed (int);            // Set seed and initialize
  96.   inline void set_rng (RNG_TYPE);        // Set generator function
  97.   inline double next ();            // Return next random number
  98.  
  99. private:
  100.   float l,u;                    // Lower/upper inclusive bounds
  101.   RNG generator;                // Pointer to generator funn
  102.   int s;                    // Shared seed value
  103.   long ix1, ix2, ix3;                // 3 generator sequence numbers
  104.   double maxran;                // Maximum random number
  105.   double prev_rnum;                // Retains previous random num
  106.   long k_buffer[KNUTH_SPECIAL];            // Buffer for Knuth's algorithm
  107.   double buffer[RND_BUF_SIZE];            // Promote random distribution
  108.   
  109.   double simple ();                // System-based RNG 
  110.   double shuffle ();                // Shuffle RNG
  111.   double one_congruential ();            // 1 linear congruential RNG
  112.   double three_congruential ();            // 3 linear congruential RNG
  113.   double subtractive ();            // Knuth subtractive RNG
  114.   void init (RNG_TYPE);                // Initialize random generator
  115. };
  116.  
  117.  
  118. // get_seed -- Return the current seed for the RNG
  119. // Input:      None
  120. // Output:     Current seed value
  121.  
  122. inline int CoolRandom::get_seed () const {
  123.   return this->s;
  124. }
  125.  
  126.  
  127. // set_seed -- Set the seed for the RNG and force a recalculation of the
  128. //             randomized cache to preclude correlation in the results
  129. // Input:      New integer seed value
  130. // Output:     None
  131.  
  132. inline void CoolRandom::set_seed (int seed) {
  133.   this->s = seed;                // Set new seed value
  134. }
  135.  
  136.  
  137. // set_rng -- Set the type of random number generator function 
  138. // Input:     RNG type
  139. // Output:    None
  140.  
  141. inline void CoolRandom::set_rng (RNG_TYPE rng) {
  142.   this->init (rng);                // Make anti-correlation buffer
  143. }
  144.  
  145.  
  146. // next -- Generate another random number
  147. // Input:  None
  148. // Output: Random number
  149.  
  150. inline double CoolRandom::next () {
  151.   return (this->*generator)();
  152. }
  153.  
  154. #endif RANDOMH                    // End RANDOMH
  155.  
  156.